﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using com.hyrentals.webcommon.filter;
using com.hyrentals.webcommon.extensions;
using com.hyrentals.logic;
using com.hyrentals.data;
using com.hyrentals.webcommon.api;

namespace com.hyrentals.webportal.Controllers
{
    [OnError(ComponentType.Account)]
    public class AccountController : BaseController
    {
        private AccountLogic accountLogic = new AccountLogic();

        [HttpGet]
        public ActionResult Login()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Login(string account, string password, bool? rememberMe)
        {
            bool rm = rememberMe ?? false;

            // server-side validation
            ViewData.ModelState.Required("lg_account", account, "Email is required.");
            ViewData.ModelState.Email("lg_account", account, "Email format is incorrect");
            ViewData.ModelState.Required("lg_pwd", password, "Password is required.");

            if (!ViewData.ModelState.IsValid)
            {
                ViewBag.Account = account ?? string.Empty;
                return View();
            }

            UserBasic user = accountLogic.ValidateUser(account);

            if (user == null)
            {
                ViewData.ModelState.AddModelError("lg_summary", "Invalid email.");
                ViewBag.Account = account ?? string.Empty;
                return View();
            }

            if (!accountLogic.ValidatePassword(password, user))
            {
                ViewData.ModelState.AddModelError("lg_summary", "Invalid password.");
                ViewBag.Account = account ?? string.Empty;
                return View();
            }

            accountLogic.SetAuthCookie(user.UserId, rm);

            Uri urlReferer = Request.UrlReferrer;
            if (urlReferer == null || urlReferer.Query == null)
                return Redirect("/");

            NameValueCollection qs = HttpUtility.ParseQueryString(urlReferer.Query);
            if (qs == null)
                return Redirect("/");

            string returnUrl = qs["returnUrl"];
            if (returnUrl == null)
                return Redirect("/");

            returnUrl = HttpUtility.UrlDecode(returnUrl);
            return Redirect(returnUrl);
        }

        [HttpPost]
        public ActionResult AjaxLogin(string account, string password, bool? rememberMe)
        {
            bool rm = rememberMe ?? false;

            List<object> errorList = new List<object>();
            // server-side validation
            ViewData.ModelState.Required("lgp_act_msg", account, "Email is required.");
            ViewData.ModelState.Email("lgp_act_msg", account, "Email format is incorrect");
            ViewData.ModelState.Required("lgp_pwd_msg", password, "Password is required.");

            if (!ViewData.ModelState.IsValid)
            {
                errorList = ViewData.ModelState.GenerateErrorList();
                return Json(new JsonResultObj
                {
                    Result = ResultStatusCode.Error,
                    Content = errorList
                });
            }
            
            UserBasic user = accountLogic.ValidateUser(account);

            if (user == null)
            {
                errorList.Add(new { id = "lgp_summary", msg = "Invalid email." });
                return Json(new JsonResultObj
                {
                    Result = ResultStatusCode.Error,
                    Content = errorList
                });
            }

            if (!accountLogic.ValidatePassword(password, user))
            {
                errorList.Add(new { id = "lgp_summary", msg = "Invalid password." });
                return Json(new JsonResultObj
                {
                    Result = ResultStatusCode.Error,
                    Content = errorList
                });
            }

            accountLogic.SetAuthCookie(user.UserId, rm);

            return Json(new JsonResultObj
            {
                Result = ResultStatusCode.Success,
                Content = string.Empty
            });
        }

        [HttpGet]
        public ActionResult Validate()
        {

            if (User.Identity.IsAuthenticated)
            {
                return Json(
                    new JsonResultObj
                    {
                        Result = ResultStatusCode.Success,
                        Content = string.Empty
                    }, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(
                   new JsonResultObj
                   {
                       Result = ResultStatusCode.Error,
                       Content = string.Empty
                   }, JsonRequestBehavior.AllowGet);
            }
        }

        [HttpGet]
        public ActionResult SignUp()
        {
            return View();
        }

        [HttpPost]
        public ActionResult SignUp(string firstName, string lastName, string email, string password)
        {
            // server-side validation
            ViewData.ModelState.Required("reg_firstname", firstName, "First name is required.");
            ViewData.ModelState.MinLength("reg_firstname", firstName, "At least 2 characters.", 2, false);
            ViewData.ModelState.MaxLength("reg_firstname", firstName, "At most 20 characters.", 20, false);

            ViewData.ModelState.Required("reg_lastname", lastName, "Last name is required.");
            ViewData.ModelState.MinLength("reg_lastname", lastName, "At least 2 characters.", 2, false);
            ViewData.ModelState.MaxLength("reg_lastname", lastName, "At most 20 characters.", 20, false);

            ViewData.ModelState.Required("reg_email", email, "Email is required.");
            ViewData.ModelState.Email("reg_email", email, "Email format is incorrect.");

            ViewData.ModelState.Required("reg_pwd", password, "Password is required.");
            ViewData.ModelState.MinLength("reg_pwd", password, "At least 6 characters.", 6, true);
            ViewData.ModelState.MaxLength("reg_pwd", password, "At most 16 characters.", 16, true);
            ViewData.ModelState.NoSpace("reg_pwd", password, "Space is not allowed in Password.");

            ViewBag.FirstName = firstName ?? string.Empty;
            ViewBag.LastName = lastName ?? string.Empty;
            ViewBag.Email = email ?? string.Empty;

            if (!ViewData.ModelState.IsValid)
            {
                return View();
            }

            

            string newUserId = Guid.NewGuid().ToString("N");
            if (accountLogic.HasEmailRegistered(email))
            {
                ViewData.ModelState.AddModelError("reg_summary", "That email address is already in use. Please log in.");
                return View();
            }

            if (!accountLogic.InsertUser(newUserId, firstName, lastName, email, password))
            {
                ViewData.ModelState.AddModelError("reg_summary", "Registration failure ,please try later.");
                return View();
            }

            UserBasic user = accountLogic.GetUser(newUserId);
            accountLogic.SetAuthCookie(user.UserId, false);

            Uri urlReferer = Request.UrlReferrer;
            if (urlReferer == null || urlReferer.Query == null)
                return Redirect("/");

            NameValueCollection qs = HttpUtility.ParseQueryString(urlReferer.Query);
            if (qs == null)
                return Redirect("/");

            string returnUrl = qs["returnUrl"];
            if (returnUrl == null)
                return Redirect("/");

            returnUrl = HttpUtility.UrlDecode(returnUrl);
            return Redirect(returnUrl);
        }

        [HttpGet]
        public ActionResult Logout(string returnUrl)
        {
            accountLogic.SignOut();
            if (string.IsNullOrWhiteSpace(returnUrl))
                return RedirectToAction("Login");

            returnUrl = HttpUtility.UrlDecode(returnUrl);
            return Redirect(returnUrl);

        }

        [HttpGet]
        public ActionResult GetUserStatus()
        {
            UserBasic currentUser = accountLogic.GetUser(User.Identity.Name);
            if (currentUser != null)
            {
                var content = new { Name = currentUser.Name };
                return Json(new JsonResultObj
                {
                    Result = ResultStatusCode.Success,
                    Content = content
                }, JsonRequestBehavior.AllowGet);

            }
            else
            {
                return Json(new JsonResultObj
                {
                    Result = ResultStatusCode.Error,
                }, JsonRequestBehavior.AllowGet);
            }

           
        }
    }
}